package com.guapi.thread;

import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.guapi.util.SpringContextUtils;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Objects;

/**
 * 使用子线程执行定时任务
 */
public class ScheduleThread implements Runnable {

    private static final Log log = LogFactory.get(ScheduleThread.class);

    private String beanName;
    private String methodName;
    private String params;
    private Object targetBean;
    private Method method;

    private Object[] multiParams;

    public void init() {
        try {
            targetBean = SpringContextUtils.getBean(beanName);
            if (params != null) {
                multiParams = params.split(",");
            }
            if (StrUtil.hasLetter(params) && multiParams.length > 0) {
                Class[] paramTypes = new Class[multiParams.length];
                for (int i = 0; i < multiParams.length; i++) {
                    paramTypes[i] = String.class;
                }
                method = targetBean.getClass().getMethod(methodName, paramTypes);
            } else {
                method = targetBean.getClass().getDeclaredMethod(methodName);
            }
            ReflectUtil.setAccessible(method);
        } catch (NoSuchMethodException e) {
            log.error("------------找不到所需要的方法------------");
            log.error("类名：" + beanName + ",方法名：" + methodName + ",参数：" + Arrays.toString(multiParams));
            e.printStackTrace();
        }
    }

    public ScheduleThread(String beanName, String methodName, String params) {
        this.beanName = beanName;
        this.methodName = methodName;
        this.params = params;
        init();
    }

    public ScheduleThread(String beanName, String methodName) {
        this(beanName, methodName, null);
    }


    @Override
    public void run() {
        log.info("------------执行定时任务------------");
        log.info("bean:{},方法:{},参数:{}", beanName, methodName, params);
        long start = System.currentTimeMillis();
        try {
            if (StrUtil.hasLetter(params)) {
                method.invoke(targetBean, multiParams);
            } else {
                method.invoke(targetBean);
            }
        } catch (Exception e) {
            log.error("------------定时任务执行异常------------");
            log.error(e);
        }
        long end = System.currentTimeMillis();

        log.info("定时任务执行耗时:{}", (end - start));
        log.info("------------定时任务执行完成------------");

    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        ScheduleThread that = (ScheduleThread) o;
        return Objects.equals(beanName, that.beanName) &&
                Objects.equals(methodName, that.methodName) &&
                Objects.equals(params, that.params);
    }

    @Override
    public int hashCode() {
        return Objects.hash(beanName, methodName, params);
    }
}
